﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using FU.Capstones.IMS.Web.Silverlight.Popups;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class ProductListViewModel : ViewModelBase
    {
        public ProductListViewModel()
        {
            Model = new ProductListModel();
            ((ProductListModel)Model).GetProductCollectionCompleted += DoGetProductCollectionCompleted;
            ((ProductListModel)Model).SearhProductCompleted += DoSearhProductCompleted;
            ((ProductListModel)Model).DeleteProductCompleted += DoDeleteProductCompleted;
            ((ProductListModel)Model).UndoDeleteProductCompleted += UndoDeleteProductCompleted;
            ((ProductListModel)Model).GetSingleProductCompleted += DoGetSingleProductCompleted;
            ((ProductListModel)Model).GetCustomerCollectionCompleted += DoGetCustomerCollectionCompleted;
            ((ProductListModel)Model).GetWarehouseCollectionCompleted += DoGetWarehouseCollectionCompleted;
            ((ProductListModel)Model).GetProductCollectionTypeCompleted += DoGetProductCollectionTypeCompleted;

            ProductCriteria = new ProductCriteria();

            ServiceCallCounter += ((ProductListModel)Model).GetProductCollectionAsync(IsShowAll);
            ServiceCallCounter += ((ProductListModel)Model).GetCustomerCollectionAsync();
            ServiceCallCounter += ((ProductListModel)Model).GetWarehouseCollectionAsync();
            ServiceCallCounter += ((ProductListModel)Model).GetProductCollectionTypeAsync(IsShowAll);

            ErrorMessageVisibility = Visibility.Collapsed;
            MessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditProduct;
            CanAdd = CurrentUser.CanAddProduct;
        }

        #region Do Completed Methods

        void DoGetWarehouseCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Warehouse> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    WarehouseCollection = e.Result.Data;
                    WarehouseCollection.Insert(0, new Warehouse() { WarehouseID = 0, WarehouseName = "Tất cả" });
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetCustomerCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Partner> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    SupplierCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSingleProductCompleted(object sender, SingleFeedbackCompletedEventArgs<Product> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    Product = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoDeleteProductCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ServiceCallCounter += ((ProductListModel)Model).GetProductCollectionTypeAsync(IsShowAll);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void UndoDeleteProductCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.ProductDetail, currentProductID);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoSearhProductCompleted(object sender, CollectionFeedbackCompletedEventArgs<Product> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ProductCollection = new PagedCollectionView(e.Result.Data);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetProductCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Product> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ProductCollection = new PagedCollectionView(e.Result.Data);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetProductCollectionTypeCompleted(object sender, CollectionFeedbackCompletedEventArgs<Product> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ProductTypeCollection = new PagedCollectionView(e.Result.Data);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        #region ViewCommand

        private DelegateCommand<Product> viewCommand;
        public DelegateCommand<Product> ViewCommand
        {
            get
            {
                if (viewCommand == null)
                {
                    viewCommand = new DelegateCommand<Product>(DoViewCommand);
                }
                return viewCommand;
            }
        }

        private void DoViewCommand(Product obj)
        {
            ServiceCallCounter += ((ProductListModel)Model).GetSingleProductAsync(obj.ProductID);
        }

        #endregion

        #region ShowAllCommand

        private DelegateCommand<object> showAllCommand;
        public DelegateCommand<object> ShowAllCommand
        {
            get
            {
                if (showAllCommand == null)
                {
                    showAllCommand = new DelegateCommand<object>(DoShowAllCommand);
                }
                return showAllCommand;
            }
        }

        private void DoShowAllCommand(object obj)
        {
            ServiceCallCounter +=
                ((ProductListModel) Model).GetProductCollectionTypeAsync(IsShowAll);
        }

        #endregion

        #region EditCommand

        private DelegateCommand<int?> editCommand;
        public DelegateCommand<int?> EditCommand
        {
            get
            {
                if (editCommand == null)
                {
                    editCommand = new DelegateCommand<int?>(DoEditCommand);
                }
                return editCommand;
            }
        }

        private void DoEditCommand(int? obj)
        {
            if (obj.HasValue)
            {
                currentProductID = obj.Value;
                var temp = ProductTypeCollection.Cast<Product>().FirstOrDefault(x => x.ProductID == currentProductID);
                if (temp.IsDelete)
                {
                    var popup = new UndoDeleteConfirmationPopup();
                    popup.Show();
                    popup.Closed += (sender, e) =>
                                        {
                                            if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                            {
                                                ServiceCallCounter += ((ProductListModel)Model).UndoDeleteProductAsync(currentProductID);
                                            }
                                        };
                }
                else
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.ProductDetail, currentProductID);
                }
            }
        }

        #endregion

        #region DeleteCommand

        private DelegateCommand<int?> deleteCommand;
        public DelegateCommand<int?> DeleteCommand
        {
            get
            {
                if (deleteCommand == null)
                {
                    deleteCommand = new DelegateCommand<int?>(DoDeleteCommand);
                }
                return deleteCommand;
            }
        }

        private void DoDeleteCommand(int? obj)
        {
            if (obj.HasValue)
            {
                DeleteConfirmationPopup popup = new DeleteConfirmationPopup();
                popup.Show();
                popup.Closed += (sender, e) =>
                                    {
                                        if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                        {
                                            ServiceCallCounter += ((ProductListModel) Model).DeleteProductAsync(obj.Value);
                                        }
                                    };
            }


        }

        #endregion

        #region CreateCommand

        private DelegateCommand<object> createCommand;
        public DelegateCommand<object> CreateCommand
        {
            get
            {
                if (createCommand == null)
                {
                    createCommand = new DelegateCommand<object>(DoCreateCommand);
                }
                return createCommand;
            }
        }

        private void DoCreateCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.ProductDetail);
        }

        #endregion

        #region SearchCommand

        private DelegateCommand<object> searchCommand;
        public DelegateCommand<object> SearchCommand
        {
            get
            {
                if (searchCommand == null)
                {
                    searchCommand = new DelegateCommand<object>(DoSearchCommand);
                }
                return searchCommand;
            }
        }

        private void DoSearchCommand(object obj)
        {
            if (ProductCriteria.SelectedWarehouse != null && ProductCriteria.SelectedWarehouse.WarehouseID != 0)
            {
                if (ProductCriteria.WarehouseIDCollection == null)
                {
                    ProductCriteria.WarehouseIDCollection = new ObservableCollection<int>();
                }
                else
                {
                    ProductCriteria.WarehouseIDCollection.Clear();
                }
                ProductCriteria.WarehouseIDCollection.Add(ProductCriteria.SelectedWarehouse.WarehouseID);
            }
            else
            {
                ProductCriteria.WarehouseIDCollection = new ObservableCollection<int>();
            }
            
            ServiceCallCounter += ((ProductListModel)Model).SearchProductAsync(ProductCriteria);
            Message = WebConstants.SearchingMessage;
        }

        #endregion

        #endregion

        #region Binding Properties

        private PagedCollectionView productCollection;
        public PagedCollectionView ProductCollection
        {
            get { return productCollection; }
            set
            {
                if (!ReferenceEquals(productCollection, value))
                {
                    productCollection = value;
                    RaisePropertyChanged(() => ProductCollection);
                }
            }
        }

        private PagedCollectionView productTypeCollection;
        public PagedCollectionView ProductTypeCollection
        {
            get { return productTypeCollection; }
            set
            {
                if (!ReferenceEquals(productTypeCollection, value))
                {
                    productTypeCollection = value;
                    RaisePropertyChanged(() => ProductTypeCollection);
                }
            }
        }

        private ObservableCollection<Warehouse> warehouseCollection;
        public ObservableCollection<Warehouse> WarehouseCollection
        {
            get { return warehouseCollection; }
            set
            {
                if (!ReferenceEquals(warehouseCollection, value))
                {
                    warehouseCollection = value;
                    RaisePropertyChanged(() => WarehouseCollection);
                }
            }
        }

        private ObservableCollection<Partner> supplierCollection;
        public ObservableCollection<Partner> SupplierCollection
        {
            get { return supplierCollection; }
            set
            {
                if (!ReferenceEquals(supplierCollection, value))
                {
                    supplierCollection = value;
                    RaisePropertyChanged(() => SupplierCollection);
                }
            }
        }

        private ProductCriteria productCriteria;
        public ProductCriteria ProductCriteria
        {
            get { return productCriteria; }
            set
            {
                if (!ReferenceEquals(productCriteria, value))
                {
                    productCriteria = value;
                    RaisePropertyChanged(() => ProductCriteria);
                }
            }
        }

        private Product product;
        public Product Product
        {
            get { return product; }
            set
            {
                if (!ReferenceEquals(product, value))
                {
                    product = value;
                    RaisePropertyChanged(() => Product);
                }
            }
        }

        #endregion

        #region Fields

        private int currentProductID = 0;

        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            //((ProductListModel)model).GetProductCollectionAsync();
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion
    }
}